home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 45
/
Aminet 45 (2001)(GTI - Schatztruhe)[!][Oct 2001].iso
/
Aminet
/
gfx
/
x11
/
x3270_3_2_16.lha
/
amiga_src
/
keypad.c
< prev
next >
Wrap
C/C++ Source or Header
|
2001-06-23
|
25KB
|
892 lines
/*
* Copyright 1993, 1994, 1995, 1996, 1999, 2000 by Paul Mattes.
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose and without fee is hereby granted,
* provided that the above copyright notice appear in all copies and that
* both that copyright notice and this permission notice appear in
* supporting documentation.
*/
/*
* keypad.c
* This module handles the keypad with buttons for each of the
* 3270 function keys.
*/
#include "globals.h"
#if defined(X3270_KEYPAD) /*[*/
#include <X11/Shell.h>
#include <X11/StringDefs.h>
#include <X11/Xaw/Command.h>
#include "appres.h"
#include "resources.h"
#include "actionsc.h"
#include "keypadc.h"
#include "kybdc.h"
#include "menubarc.h"
#include "popupsc.h"
#include "screenc.h"
#include "utilc.h"
#include "keypad.bm"
enum kp_placement kp_placement;
#define NUM_ROWS 4
#define NUM_VROWS 15
#define BORDER 1
#define TOP_MARGIN 6
#define BOTTOM_MARGIN 6
#define SPACING 2
#define FAT_SPACING 3
#define VGAP 4
#define HGAP 4
#define SIDE_MARGIN 4
#define HORIZ_WIDTH \
(SIDE_MARGIN + \
12*(pf_width+2*BORDER) + \
11*SPACING + \
HGAP + \
3*(pa_width+2*BORDER) + \
2*SPACING + \
SIDE_MARGIN)
#define VERT_WIDTH \
(SIDE_MARGIN + \
3*(pa_width+2*BORDER) + \
2*SPACING + \
SIDE_MARGIN)
/*
* Table of 3278 key labels and actions
*/
struct button_list {
const char *label;
const char *name;
const char *bits;
int width;
int height;
XtActionProc action;
const char *parm;
};
Boolean keypad_changed = False;
static char Lg[] = "large";
static char Bm[] = "bm";
static char Sm[] = "small";
static struct button_list pf_list[] = {
{ "PF13", Lg, CN, 0, 0, PF_action, "13" },
{ "PF14", Lg, CN, 0, 0, PF_action, "14" },
{ "PF15", Lg, CN, 0, 0, PF_action, "15" },
{ "PF16", Lg, CN, 0, 0, PF_action, "16" },
{ "PF17", Lg, CN, 0, 0, PF_action, "17" },
{ "PF18", Lg, CN, 0, 0, PF_action, "18" },
{ "PF19", Lg, CN, 0, 0, PF_action, "19" },
{ "PF20", Lg, CN, 0, 0, PF_action, "20" },
{ "PF21", Lg, CN, 0, 0, PF_action, "21" },
{ "PF22", Lg, CN, 0, 0, PF_action, "22" },
{ "PF23", Lg, CN, 0, 0, PF_action, "23" },
{ "PF24", Lg, CN, 0, 0, PF_action, "24" },
{ "PF1", Lg, CN, 0, 0, PF_action, "1" },
{ "PF2", Lg, CN, 0, 0, PF_action, "2" },
{ "PF3", Lg, CN, 0, 0, PF_action, "3" },
{ "PF4", Lg, CN, 0, 0, PF_action, "4" },
{ "PF5", Lg, CN, 0, 0, PF_action, "5" },
{ "PF6", Lg, CN, 0, 0, PF_action, "6" },
{ "PF7", Lg, CN, 0, 0, PF_action, "7" },
{ "PF8", Lg, CN, 0, 0, PF_action, "8" },
{ "PF9", Lg, CN, 0, 0, PF_action, "9" },
{ "PF10", Lg, CN, 0, 0, PF_action, "10" },
{ "PF11", Lg, CN, 0, 0, PF_action, "11" },
{ "PF12", Lg, CN, 0, 0, PF_action, "12" }
};
#define PF_SZ (sizeof(pf_list)/sizeof(pf_list[0]))
static struct button_list pad_list[] = {
{ "PA1", Lg, CN, 0, 0, PA_action, "1" },
{ "PA2", Lg, CN, 0, 0, PA_action, "2" },
{ "PA3", Lg, CN, 0, 0, PA_action, "3" },
{ 0, 0, 0, 0 },
{ "Up" , Bm, (char *)up_bits, up_width, up_height,
Up_action, CN },
{ 0, 0, 0, 0 },
{ "Left", Bm, (char *)left_bits, left_width, left_height,
Left_action, CN },
{ "Home", Bm, (char *)home_bits, home_width, home_height,
Home_action, CN },
{ "Right", Bm, (char *)right_bits, right_width, right_height,
Right_action, CN },
{ 0, 0, 0, 0 },
{ "Down", Bm, (char *)down_bits, down_width, down_height,
Down_action, CN },
{ 0, 0, 0, 0 },
};
#define PAD_SZ (sizeof(pad_list)/sizeof(pad_list[0]))
static struct button_list lower_list[] = {
{ "Clear", Sm, CN, 0, 0, Clear_action, CN },
{ "Reset", Sm, CN, 0, 0, Reset_action, CN },
{ "Ins", Bm, (char *)ins_bits, ins_width, ins_height,
Insert_action, CN },
{ "Del", Bm, (char *)del_bits, del_width, del_height,
Delete_action, CN },
{ "Erase\nEOF", Sm, CN, 0, 0, EraseEOF_action, CN },
{ "Erase\nInput", Sm, CN, 0, 0, EraseInput_action,CN },
{ "Dup", Sm, CN, 0, 0, Dup_action, CN },
{ "Field\nMark", Sm, CN, 0, 0, FieldMark_action,CN },
{ "Sys\nReq", Sm, CN, 0, 0, SysReq_action, CN },
{ "Cursor\nSelect", Sm, CN, 0, 0, CursorSelect_action,CN },
{ "Attn", Sm, CN, 0, 0, Attn_action, CN },
{ "Compose", Sm, CN, 0, 0, Compose_action, CN },
{ "Btab", Bm, (char *)btab_bits, btab_width, btab_height,
BackTab_action, CN },
{ "Tab", Bm, (char *)tab_bits, tab_width, tab_height,
Tab_action, CN },
{ "Newline", Bm, (char *)newline_bits, newline_width, newline_height,
Newline_action, CN },
{ "Enter", Sm, CN, 0, 0, Enter_action, CN }
};
#define LOWER_SZ (sizeof(lower_list)/sizeof(lower_list[0]))
static struct button_list vpf_list[] = {
{ "PF1", Lg, CN, 0, 0, PF_action, "1" },
{ "PF2", Lg, CN, 0, 0, PF_action, "2" },
{ "PF3", Lg, CN, 0, 0, PF_action, "3" },
{ "PF4", Lg, CN, 0, 0, PF_action, "4" },
{ "PF5", Lg, CN, 0, 0, PF_action, "5" },
{ "PF6", Lg, CN, 0, 0, PF_action, "6" },
{ "PF7", Lg, CN, 0, 0, PF_action, "7" },
{ "PF8", Lg, CN, 0, 0, PF_action, "8" },
{ "PF9", Lg, CN, 0, 0, PF_action, "9" },
{ "PF10", Lg, CN, 0, 0, PF_action, "10" },
{ "PF11", Lg, CN, 0, 0, PF_action, "11" },
{ "PF12", Lg, CN, 0, 0, PF_action, "12" },
};
#define VPF_SZ (sizeof(vpf_list)/sizeof(vpf_list[0]))
static struct button_list vspf_list[] = {
{ "PF13", Lg, CN, 0, 0, PF_action, "13" },
{ "PF14", Lg, CN, 0, 0, PF_action, "14" },
{ "PF15", Lg, CN, 0, 0, PF_action, "15" },
{ "PF16", Lg, CN, 0, 0, PF_action, "16" },
{ "PF17", Lg, CN, 0, 0, PF_action, "17" },
{ "PF18", Lg, CN, 0, 0, PF_action, "18" },
{ "PF19", Lg, CN, 0, 0, PF_action, "19" },
{ "PF20", Lg, CN, 0, 0, PF_action, "20" },
{ "PF21", Lg, CN, 0, 0, PF_action, "21" },
{ "PF22", Lg, CN, 0, 0, PF_action, "22" },
{ "PF23", Lg, CN, 0, 0, PF_action, "23" },
{ "PF24", Lg, CN, 0, 0, PF_action, "24" },
};
static Widget vpf_w[2][VPF_SZ];
static struct button_list vpad_list[] = {
{ 0, 0, 0 },
{ "Up" , Bm, (char *)up_bits, up_width, up_height,
Up_action, CN },
{ 0, 0, 0 },
{ "Left" , Bm, (char *)left_bits, left_width, left_height,
Left_action, CN },
{ "Home", Bm, (char *)home_bits, home_width, home_height,
Home_action, CN },
{ "Right" , Bm, (char *)right_bits, right_width, right_height,
Right_action, CN },
{ "Ins", Bm, (char *)ins_bits, ins_width, ins_height,
Insert_action, CN },
{ "Down" , Bm, (char *)down_bits, down_width, down_height,
Down_action, CN },
{ "Del", Bm, (char *)del_bits, del_width, del_height,
Delete_action, CN },
{ "PA1", Lg, CN, 0, 0, PA_action, "1" },
{ "PA2", Lg, CN, 0, 0, PA_action, "2" },
{ "PA3", Lg, CN, 0, 0, PA_action, "3" },
};
#define VPAD_SZ (sizeof(vpad_list)/sizeof(vpad_list[0]))
static struct button_list vfn_list[] = {
{ "Btab", Bm, (char *)btab_bits, btab_width, btab_height,
BackTab_action, CN },
{ "Tab", Bm, (char *)tab_bits, tab_width, tab_height,
Tab_action, CN },
{ "Clear", Sm, CN, 0, 0, Clear_action, CN },
{ "Reset", Sm, CN, 0, 0, Reset_action, CN },
{ "Erase\nEOF", Sm, CN, 0, 0, EraseEOF_action, CN },
{ "Erase\nInput", Sm, CN, 0, 0, EraseInput_action,CN },
{ "Dup", Sm, CN, 0, 0, Dup_action, CN },
{ "Field\nMark", Sm, CN, 0, 0, FieldMark_action,CN },
{ "Sys\nReq", Sm, CN, 0, 0, SysReq_action, CN },
{ "Cursor\nSelect", Sm, CN, 0, 0, CursorSelect_action,CN },
{ "Attn", Sm, CN, 0, 0, Attn_action, CN },
{ "Compose", Sm, CN, 0, 0, Compose_action, CN },
{ "Newline", Bm, (char *)newline_bits, newline_width, newline_height,
Newline_action, CN },
{ "Enter", Sm, CN, 0, 0, Enter_action, CN },
};
#define VFN_SZ (sizeof(vfn_list)/sizeof(vfn_list[0]))
static Dimension pf_width;
static Dimension key_height;
static Dimension pa_width;
static Dimension key_width;
static Dimension large_key_width;
static Position sm_x, sm_y;
static Dimension sm_w, sm_h;
static Widget keypad_container = (Widget) NULL;
static XtTranslations keypad_t00 = (XtTranslations) NULL;
static XtTranslations keypad_t0 = (XtTranslations) NULL;
static XtTranslations saved_xt = (XtTranslations) NULL;
/* Initialize the keypad placement from the keypad resource. */
void
keypad_placement_init(void)
{
if (!strcmp(appres.keypad, KpLeft))
kp_placement = kp_left;
else if (!strcmp(appres.keypad, KpRight))
kp_placement = kp_right;
else if (!strcmp(appres.keypad, KpBottom))
kp_placement = kp_bottom;
else if (!strcmp(appres.keypad, KpIntegral))
kp_placement = kp_integral;
else
xs_error("Unknown value for %s", ResKeypad);
}
/*
* Callback for keypad buttons. Simply calls the function pointed to by the
* client data.
*/
static void
callfn(Widget w unused, XtPointer client_data, XtPointer call_data unused)
{
struct button_list *keyd = (struct button_list *) client_data;
action_internal(keyd->action, IA_KEYPAD, keyd->parm, CN);
}
/*
* Create a button.
*/
static Widget
make_a_button(Widget container, Position x, Position y, Dimension w,
Dimension h, struct button_list *keyd)
{
Widget command;
Pixmap pixmap;
if (!keyd->label)
return (Widget) 0;
command = XtVaCreateManagedWidget(
keyd->name, commandWidgetClass, container,
XtNx, x,
XtNy, y,
XtNwidth, w,
XtNheight, h,
XtNresize, False,
NULL);
XtAddCallback(command, XtNcallback, callfn, (XtPointer)keyd);
if (keyd->bits) {
pixmap = XCreateBitmapFromData(display, root_window,
keyd->bits, keyd->width, keyd->height);
XtVaSetValues(command, XtNbitmap, pixmap, NULL);
} else
XtVaSetValues(command, XtNlabel, keyd->label, NULL);
return command;
}
/*
* Create the keys for a horizontal keypad
*/
static void
keypad_keys_horiz(Widget container)
{
unsigned i;
Position row, col;
Position x0, y0;
/* PF Keys */
row = col = 0;
x0 = SIDE_MARGIN;
y0 = TOP_MARGIN;
for (i = 0; i < PF_SZ; i++) {
(void) make_a_button(container,
(Position)(x0 + (col*(pf_width+2*BORDER+SPACING))),
(Position)(y0 + (row*(key_height+2*BORDER+SPACING))),
pf_width,
key_height,
&pf_list[i]);
if (++col >= 12) {
col = 0;
row++;
}
}
/* Keypad */
row = col = 0;
x0 = SIDE_MARGIN + 12*(pf_width+2*BORDER+SPACING) + HGAP;
y0 = TOP_MARGIN;
for (i = 0; i < PAD_SZ; i++) {
(void) make_a_button(container,
(Position)(x0 + (col*(pa_width+2*BORDER+SPACING))),
(Position)(y0 + (row*(key_height+2*BORDER+SPACING))),
pa_width,
key_height,
&pad_list[i]);
if (++col >= 3) {
col = 0;
if (++row == 1)
y0 += VGAP;
}
}
/* Bottom */
row = col = 0;
x0 = SIDE_MARGIN;
y0 = TOP_MARGIN + 2*(key_height+2*BORDER+SPACING) + VGAP;
for (i = 0; i < LOWER_SZ; i++) {
(void) make_a_button(container,
(Position)(x0 + (col*(key_width+2*BORDER+FAT_SPACING))),
(Position)(y0 + (row*(key_height+2*BORDER+SPACING))),
key_width,
key_height,
&lower_list[i]);
if (++row >= 2) {
++col;
row = 0;
}
}
}
static Boolean vert_keypad = False;
static Widget spf_container;
/*
* Create the keys for a vertical keypad.
*/
static void
keypad_keys_vert(Widget container)
{
unsigned i;
Position row, col;
Position x0, y0;
Widget c1, c2;
vert_keypad = True;
/* Container for shifted PF keys */
spf_container = XtVaCreateManagedWidget(
"shift", compositeWidgetClass, container,
XtNmappedWhenManaged, False,
XtNborderWidth, 0,
XtNwidth, VERT_WIDTH,
XtNheight, TOP_MARGIN+4*(key_height+2*BORDER)+3*SPACING,
NULL);
if (appres.mono)
XtVaSetValues(spf_container, XtNbackgroundPixmap, gray, NULL);
else
XtVaSetValues(spf_container, XtNbackground, keypadbg_pixel,
NULL);
/* PF keys */
if (appres.invert_kpshift) {
c1 = spf_container;
c2 = container;
} else {
c1 = container;
c2 = spf_container;
}
row = col = 0;
x0 = SIDE_MARGIN;
y0 = TOP_MARGIN;
for (i = 0; i < VPF_SZ; i++) {
vpf_w[0][i] = make_a_button(c1,
(Position)(x0 + (col*(pa_width+2*BORDER+SPACING))),
(Position)(y0 + (row*(key_height+2*BORDER+SPACING))),
pa_width,
key_height,
&vpf_list[i]);
vpf_w[1][i] = make_a_button(c2,
(Position)(x0 + (col*(pa_width+2*BORDER+SPACING))),
(Position)(y0 + (row*(key_height+2*BORDER+SPACING))),
pa_width,
key_height,
&vspf_list[i]);
if (++col >= 3) {
col = 0;
row++;
}
}
/* Cursor and PA keys */
for (i = 0; i < VPAD_SZ; i++) {
(void) make_a_button(container,
(Position)(x0 + (col*(pa_width+2*BORDER+SPACING))),
(Position)(y0 + (row*(key_height+2*BORDER+SPACING))),
pa_width,
key_height,
&vpad_list[i]);
if (++col >= 3) {
col = 0;
row++;
}
}
/* Other keys */
for (i = 0; i < VFN_SZ; i++) {
(void) make_a_button(container,
(Position)(x0 + (col*(large_key_width+2*BORDER+SPACING))),
(Position)(y0 + (row*(key_height+2*BORDER+SPACING))),
large_key_width,
key_height,
&vfn_list[i]);
if (++col >= 2) {
col = 0;
row++;
}
}
}
static Dimension
get_keypad_dimension(const char *name)
{
char *rname;
char *d;
long v;
rname = xs_buffer("%s.%s", ResKeypad, name);
if ((d = get_resource(rname)) == CN)
xs_error("Cannot find %s resource", ResKeypad);
XtFree(rname);
if ((v = strtol(d, (char **)0, 0)) <= 0)
xs_error("Illegal %s resource", ResKeypad);
return (Dimension)v;
}
static void
init_keypad_dimensions(void)
{
static Boolean done = False;
if (done)
return;
key_height = get_keypad_dimension(ResKeyHeight);
key_width = get_keypad_dimension(ResKeyWidth);
pf_width = get_keypad_dimension(ResPfWidth);
pa_width = get_keypad_dimension(ResPaWidth);
large_key_width = get_keypad_dimension(ResLargeKeyWidth);
done = True;
}
Dimension
min_keypad_width(void)
{
init_keypad_dimensions();
return HORIZ_WIDTH;
}
Dimension
keypad_qheight(void)
{
init_keypad_dimensions();
return TOP_MARGIN +
(NUM_ROWS*(key_height+2*BORDER)) + (NUM_ROWS-1)*SPACING + VGAP +
BOTTOM_MARGIN;
}
/*
* Create a keypad.
*/
Widget
keypad_init(Widget container, Dimension voffset, Dimension screen_width, Boolean floating, Boolean vert)
{
static Widget key_pad;
Dimension height;
Dimension width = screen_width;
Dimension hoffset;
init_keypad_dimensions();
/* Figure out what dimensions to use */
if (vert)
width = VERT_WIDTH;
else
width = HORIZ_WIDTH;
if (vert)
height = TOP_MARGIN +
(NUM_VROWS*(key_height+2*BORDER)) + (NUM_VROWS-1)*SPACING +
BOTTOM_MARGIN;
else
height = keypad_qheight();
/* Create a container */
if (screen_width > width)
hoffset = ((screen_width - width) / (unsigned) 2) & ~1;
else
hoffset = 0;
if (voffset & 1)
voffset++;
if (key_pad == (Widget)NULL) {
key_pad = XtVaCreateManagedWidget(
"keyPad", compositeWidgetClass, container,
XtNx, hoffset,
XtNy, voffset,
XtNborderWidth, (Dimension) (floating ? 1 : 0),
XtNwidth, width,
XtNheight, height,
NULL);
if (appres.mono)
XtVaSetValues(key_pad, XtNbackgroundPixmap, gray,
NULL);
else
XtVaSetValues(key_pad, XtNbackground, keypadbg_pixel,
NULL);
/* Create the keys */
if (vert)
keypad_keys_vert(key_pad);
else
keypad_keys_horiz(key_pad);
} else {
XtVaSetValues(key_pad,
XtNx, hoffset,
XtNy, voffset,
NULL);
}
return key_pad;
}
/*
* Swap PF1-12 and PF13-24 on the vertical popup keypad, by mapping or
* unmapping the window containing the shifted keys.
*/
void
keypad_shift(void)
{
if (!vert_keypad || !XtIsRealized(spf_container))
return;
if (shifted)
XtMapWidget(spf_container);
else
XtUnmapWidget(spf_container);
}
/*
* Keypad popup
*/
Widget keypad_shell = NULL;
Boolean keypad_popped = False;
static Boolean up_once = False;
static Position kset_x, kset_y;
static Position kmove_x, kmove_y;
static Dimension decor_width, decor_height;
static enum { WA_UNKNOWN, WA_ALL, WA_PARTIAL, WA_NONE } wa_mode = WA_UNKNOWN;
/*
* Called when the main screen is first exposed, to pop up the keypad the
* first time
*/
void
keypad_first_up(void)
{
if (!appres.keypad_on || kp_placement == kp_integral || up_once)
return;
keypad_popup_init();
popup_popup(keypad_shell, XtGrabNone);
}
/* Called when the keypad popup pops up or down */
static void
keypad_updown(Widget w unused, XtPointer client_data,
XtPointer call_data unused)
{
appres.keypad_on = keypad_popped = *(Boolean *)client_data;
if (keypad_popped) {
up_once = True;
toplevel_geometry(&sm_x, &sm_y, &sm_w, &sm_h);
XtVaGetValues(keypad_shell, XtNx, &kset_x, XtNy, &kset_y, NULL);
wa_mode = WA_UNKNOWN;
}
menubar_keypad_changed();
}
static Boolean TrueD = True;
static Boolean *TrueP = &TrueD;
static Boolean FalseD = False;
static Boolean *FalseP = &FalseD;
static enum placement *pp;
/* Create the pop-up keypad */
void
keypad_popup_init(void)
{
Widget w;
Dimension height, width, border;
Boolean vert = False;
if (keypad_shell != NULL)
return;
switch (kp_placement) {
case kp_left:
vert = True;
pp = LeftP;
break;
case kp_right:
vert = True;
pp = RightP;
break;
case kp_bottom:
vert = False;
pp = BottomP;
break;
case kp_integral: /* can't happen */
return;
}
/* Create a popup shell */
keypad_shell = XtVaCreatePopupShell(
"keypadPopup", transientShellWidgetClass, toplevel,
NULL);
XtAddCallback(keypad_shell, XtNpopupCallback, place_popup,
(XtPointer)pp);
XtAddCallback(keypad_shell, XtNpopupCallback, keypad_updown,
(XtPointer) TrueP);
XtAddCallback(keypad_shell, XtNpopdownCallback, keypad_updown,
(XtPointer) FalseP);
/* Create a keypad in the popup */
keypad_container = XtVaCreateManagedWidget(
"container", compositeWidgetClass, keypad_shell,
XtNborderWidth, 0,
XtNheight, 10,
XtNwidth, 10,
NULL);
w = keypad_init(keypad_container, 0, 0, True, vert);
/* Fix the window size */
XtVaGetValues(w,
XtNheight, &height,
XtNwidth, &width,
XtNborderWidth, &border,
NULL);
height += 2*border;
width += 2*border;
XtVaSetValues(keypad_container,
XtNheight, height,
XtNwidth, width,
NULL);
XtVaSetValues(keypad_shell,
XtNheight, height,
XtNwidth, width,
XtNbaseHeight, height,
XtNbaseWidth, width,
XtNminHeight, height,
XtNminWidth, width,
XtNmaxHeight, height,
XtNmaxWidth, width,
NULL);
/* Make keystrokes in the popup apply to the main window */
save_00translations(keypad_container, &keypad_t00);
set_translations(keypad_container, (XtTranslations *)NULL, &keypad_t0);
if (saved_xt != (XtTranslations) NULL) {
XtOverrideTranslations(keypad_container, saved_xt);
saved_xt = (XtTranslations) NULL;
}
}
/* Set a temporary keymap. */
void
keypad_set_temp_keymap(XtTranslations trans)
{
if (keypad_container != (Widget) NULL) {
if (trans == (XtTranslations)NULL) {
trans = keypad_t0;
XtUninstallTranslations(keypad_container);
}
XtOverrideTranslations(keypad_container, trans);
saved_xt = (XtTranslations) NULL;
} else
saved_xt = trans;
}
/* Change the baseleve keymap. */
void
keypad_set_keymap(void)
{
if (keypad_container == (Widget)NULL)
return;
XtUninstallTranslations(keypad_container);
set_translations(keypad_container, &keypad_t00, &keypad_t0);
}
static void
measure_move(XtPointer closure unused, XtIntervalId *id unused)
{
Position x, y;
XtVaGetValues(keypad_shell, XtNx, &x, XtNy, &y, NULL);
if (x != kmove_x || y != kmove_y) {
if (kmove_x - x < 0 && kmove_y - y < 0) {
/*
* The window manager shifts by exactly the decoration
* size (mwm, olwm).
*/
wa_mode = WA_ALL;
} else {
/*
* The window manager shifts by something less than the
* decoration size (twm).
*/
wa_mode = WA_PARTIAL;
XtVaSetValues(keypad_shell,
XtNx,
x + decor_width + (decor_width - (kmove_x - x)),
XtNy,
y + decor_height + (decor_height - (kmove_y - y)),
NULL);
}
} else {
/*
* The window manager leaves the window exactly where we
* asked (fvwm).
*/
XtVaSetValues(keypad_shell,
XtNx, x + decor_width,
XtNy, y + decor_height,
NULL);
wa_mode = WA_NONE;
}
}
/* Move the keypad. */
void
keypad_move(void)
{
Position x, y;
Dimension w, h;
Position x0, y0;
Dimension w0, h0;
Dimension kw0;
if (!keypad_popped)
return;
toplevel_geometry(&x, &y, &w, &h);
if (x == sm_x && y == sm_y && w == sm_w && h == sm_h)
return;
XtVaGetValues(toplevel,
XtNx, &x0,
XtNy, &y0,
XtNwidth, &w0,
XtNheight, &h0,
NULL);
switch (kp_placement) {
case kp_left:
XtVaGetValues(keypad_shell, XtNwidth, &kw0, NULL);
switch (wa_mode) {
case WA_NONE:
kmove_x = x0 - kw0 - 2 - (w - w0);
kmove_y = y0;
break;
case WA_PARTIAL:
kmove_x = x - kw0 - 2 - (w - w0) + decor_width;
kmove_y = y + decor_height;
break;
case WA_ALL:
case WA_UNKNOWN:
kmove_x = x - kw0 - 2 - (w - w0);
kmove_y = y;
break;
}
break;
case kp_right:
switch (wa_mode) {
case WA_NONE:
kmove_x = x0 + w + 2;
kmove_y = y0;
break;
case WA_PARTIAL:
kmove_x = x + w + 2 + decor_width;
kmove_y = y + decor_height;
break;
case WA_ALL:
case WA_UNKNOWN:
kmove_x = x + w + 2;
kmove_y = y;
break;
}
break;
case kp_bottom:
switch (wa_mode) {
case WA_NONE:
kmove_x = x0;
kmove_y = y0 + h + 2;
break;
case WA_PARTIAL:
kmove_x = x + decor_width;
kmove_y = y + h + 2 + decor_height;
break;
case WA_ALL:
case WA_UNKNOWN:
kmove_x = x;
kmove_y = y + h + 2;
break;
}
break;
case kp_integral: /* can't happen */
return;
}
XtVaSetValues(keypad_shell,
XtNx, kmove_x,
XtNy, kmove_y,
NULL);
if (wa_mode == WA_UNKNOWN)
XtAppAddTimeOut(appcontext, 250, measure_move, 0);
}
/*
* Handler for ReparentNotify events on the keypad. If the event is a
* reparent (as opposed to an un-reparent), measures the dimensions of the
* window manager decorations and stores them in decor_width and decor_height.
*/
void
PA_ReparentNotify_action(Widget w unused, XEvent *event, String *params unused,
Cardinal *num_params unused)
{
XReparentEvent *e = (XReparentEvent *)event;
if (e->parent != root_window) {
Position x, y;
XtVaGetValues(keypad_shell, XtNx, &x, XtNy, &y, NULL);
if (x > kset_x && y > kset_y) {
decor_width = x - kset_x;
decor_height = y - kset_y;
}
}
}
#endif /*]*/